/*
Problem Id:1024  User Id:tq 
Memory:64K  Time:15MS
Language:C++  Result:Accepted


	author: TangQiao , Wind @ Beijing Normal University

	problem name: Machine Schedule
	
	source :  BNU Online Judge
	
	problem type: 图论,求二部图的最小覆盖,由定理可得,最小覆盖等于最大匹配.
	
	problem description: 机器A,B事先处于0状态,有一些任务既可以用A机器的M状态来完成,也可以
	B机器的N状态来完成,给你一组任务,让你安排好任务的顺序,让AB机器以最少的转换状态次数完成
	所有任务.
	
	problem solution: 抽象成二部图,一边是A机器的状态,另一边是B机器的状态,如果一个任务可以
	由A机器的状态P,和B机器的状态Q完成,则在P,Q之间有一条边.
	
	
	date : 2005.7.8   7.2练习赛后未完成的题补做

	
*/

#include <stdio.h>
#include <string.h>
#define MAXN 101 

int n,m,k;

int map[MAXN][MAXN];
int ans;
int cx[MAXN],cy[MAXN],sx[MAXN],sy[MAXN];

int path(int u)
{
	int v;
	int i;

	sx[u]=1;
	for (v=1;v<=m;v++)
		if (map[u][v]==1 && !sy[v])
		{
			sy[v]=1;
			if ( !cy[v] || path(cy[v]))
			{
				cx[u]=v;
				cy[v]=u;
				return 1;
			}
		}
	return 0;
}


void solve()
{
	int i;
	memset(cx,0,sizeof(cx));
	memset(cy,0,sizeof(cy));
	ans=0;
	for (i=1;i<=n;i++)
		if (!cx[i])
		{
			memset(sx,0,sizeof(sx));
			memset(sy,0,sizeof(sy));
			ans+=path(i);
		}


}


main()
{
	int i,j,a,b;
	while (1)
	{
		scanf("%d", &n);
		if (n==0) break;
		scanf("%d%d", &m, &k);
		memset(map,0,sizeof(map));
		for (i=1;i<=k;i++)
		{
			scanf("%d%d%d", &j, &a, &b);
			map[a][b]=1;
		}
		solve();
		printf("%d\n", ans);

	}
	

	return 0;
}